﻿using App.Cache;
using App.Extension;
using CSRedis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog.Fluent;
using Simple.BasicNet.Core;
using Simple.BasicNet.Core.Atrributes;
using Simple.BasicNet.Core.Handle;
using Simple.BasicNet.Core.Net;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;

/*********************************************************
 * 命名空间 App.Handle
 * 接口名称 BasicHandler
 * 开发人员：11920
 * 创建时间：2023/4/14 10:35:00
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace App.Handle
{
	[NumberRange(0x10,0x20)]
	public class BasicHandler:BaseHandle
	{
		[Autowired]
		private ILogger logger { get; set; }

		[Autowired]
		private IRedisClientService cache { get; set; }
		[Autowired]
		private ServiceConfigution configution { get; set; }
		[Autowired]
		private VersionUpgradeHanlder versionUpgradeHanlder { get; set; }

		[Autowired]
		private IClientManager clientManager { get; set;	 }
		public BasicHandler()
		{

		}
		[MessageNumber(0x10)]
		public void Login()
		{
			byte[] LoginReplyBuf = null;
			var idtcontext = context as IDTContext;
			string msgforsignalr = "";

			IDTProtocolPack.SetDeviceInfo(idtcontext);



			switch (idtcontext.Device.eProductType)
			{
				case eProductType.SendTable:
					logger.Info($"沙盘【{idtcontext.Device.SN}】已连接");

					break;
				case eProductType.Table:
					logger.Info($"操作台【{idtcontext.Device.SN}】已连接");

					break;
				default:
					break;
			}

		

			if (idtcontext.Device.eProductType == eProductType.SendTable && string.IsNullOrEmpty(idtcontext.Device.ParentDeviceID))
			{
				idtcontext.DeviceStatus = DeviceStatus.Unlogin;
				LoginReplyBuf = LoginReply(idtcontext.CurrentPack.CommandID,eReceivePackType.BadRequest);
			}
			else
			{
				int clientType = idtcontext.Device.eProductType == eProductType.SendTable ? 0 : 2;
					idtcontext.CreateIignalRConneciont().Wait();
					var vh = versionUpgradeHanlder.CheckVersion(idtcontext.Device.SN, clientType, idtcontext.Device.WareVersion);
					vh.Wait();
					logger.Info($"当前固件版本：{idtcontext.Device.WareVersion}，{(versionUpgradeHanlder.CheckResult ? "有新版本" : "最新版本")}");
					idtcontext.DeviceStatus = DeviceStatus.LoginSuccess;

					LoginReplyBuf = LoginReply(idtcontext.CurrentPack.CommandID, eReceivePackType.Success, versionUpgradeHanlder.CheckResult ? 1 : 0);

					context.Send(LoginReplyBuf);
					idtcontext.RefreshHeartTime();
				if (idtcontext.Device.IsRelogin)
				{
					var s = string.Join(" ", LoginReplyBuf);
					logger.Info(s);
				}
				cache.SetAsync($"device:{idtcontext.Device.SN}:info", msgforsignalr, 0).Wait();
				//msgforsignalr = JsonConvert.SerializeObject(new { cmd = commandId, data = new { DeviceSn = sn, Manufacturer = manufacture, Version = wareVersion, ProductType = productType, ParentDeviceID = parentDeviceID, AuthorizeKey = authorizeKey, IsRelogin = isRelogin } });
			}
			logger.Info(idtcontext.GetDeviceInfo());
		}

		[MessageNumber(0x14)]
		public void ReLogin()
		{
			Login();
		}


		[MessageNumber(0x11)]
		public void ReceiveDeviceInfo()
		{
			IDTContext iDTContext = context.GetContext<IDTContext>();
			string msgforsignalr = string.Empty;
			logger.Info("ControllerDataSync==========");
			msgforsignalr = "";
			byte[] dataLengthBuf = new byte[4];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 4, dataLengthBuf, 0, dataLengthBuf.Length);
			Array.Reverse(dataLengthBuf);
			int dataLength = BitConverter.ToInt32(dataLengthBuf);

			byte[] dataContentsBuf = new byte[dataLength];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 8, dataContentsBuf, 0, dataLength);
			string dataContents = Encoding.UTF8.GetString(dataContentsBuf);
			logger.Info($"dataContents=>:{dataContents}");
			eReceivePackType commandStatus =eReceivePackType.Success;
			JObject jObject = null;
			if (string.IsNullOrWhiteSpace(dataContents))
			{
				commandStatus = eReceivePackType.JsonDesFail;
			}
			else
			{
				try
				{
					jObject = JsonConvert.DeserializeObject<JObject>(dataContents);
				}
				catch (Exception)
				{
					commandStatus = eReceivePackType.JsonDesFail;
				}
			}
			object replyJson = null;
			if (commandStatus == 0)
			{
				int cmd = int.Parse(jObject["cmd"].ToString());
				switch (cmd)
				{
					case 0x01:
						int ptype = iDTContext.GetPType();
						if (ptype == 64)
						{
							bool r = true;
							foreach (var item in jObject["join"])
							{
								if (item["id"].ToString() == "0000000000000000")
								{
									r = false;
									break;
								}
							}
							if (r)
							{
								msgforsignalr = JsonConvert.SerializeObject(new { cmd = jObject["cmd"], data = new { deviceSn = iDTContext.Device.SN, join = jObject["join"] } });
							}
							else
							{
								commandStatus =eReceivePackType.BadRequest;
							}
						}
						else if (ptype == 65)
						{
							msgforsignalr = JsonConvert.SerializeObject(jObject);
						}


						replyJson = new { cmd = 0x01, devID = "" };

						break;

					case 0x02:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x02, devID = jObject["curId"].ToString() };
						break;
					case 0x03:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x03, devID = "" };
						break;
					case 0x04:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x04, devID = jObject["curId"].ToString() };
						break;
					case 0x05:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x05, devID = jObject["curId"].ToString() };
						break;
					case 0x06:
						var dataObj = new { cmd = jObject["cmd"], data = new { DeviceSn = iDTContext.Device.SN, time = jObject["time"], date = jObject["date"], reset = jObject["reset"] ?? 0, bindState = jObject["bindState"] ?? 0 } };
						msgforsignalr = JsonConvert.SerializeObject(dataObj);
						//WebSocketConnectionManager.Instance.UpdateWebSocketType(sn, (int)dataObj.data.reset, (int)dataObj.data.netMode, (int)dataObj.data.bindState, (int)dataObj.data.mode, (int)dataObj.data.assessOnoff);
						replyJson = new { cmd = 0x06, devID = "" };
						break;
					case 0x07:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x07, devID = jObject["curId"].ToString() };
						break;
					case 0x08:
						msgforsignalr = JsonConvert.SerializeObject(jObject);
						replyJson = new { cmd = 0x08, devID = "" };
						break;

						//case 0x03:
						//    msgforsignalr = JsonConvert.SerializeObject(new { type = jObject["type"], data = new { DeviceSn = sn, binds = jObject["soil"] } });
						//    break;

				}
				if (replyJson != null)
				{
					logger.Info($"终端数据应答包：{JsonConvert.SerializeObject(replyJson)}");
					iDTContext.SendSignalR(msgforsignalr);

				}
				//socketHandler.SendToWebServer(Id, json);
			}
			var replyBuffer = ReceiveDeviceInfoReply(context.CurrentPack.CommandID,commandStatus, replyJson == null ? "" : JsonConvert.SerializeObject(replyJson));
			context.Send(replyBuffer);
		}

		[MessageNumber(0x12)]
		public void ClientReply()
		{
			var CommandStatus = context.CurrentPack.ReceiveBuffer[4];
			if (CommandStatus != 0)
			{
				return;
			}
			var downLoadDataId = new byte[32];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 5, downLoadDataId, 0, downLoadDataId.Length);
			string commandId = Encoding.UTF8.GetString(downLoadDataId);
			IDTContext idtContext=context.GetContext<IDTContext>();
			if (idtContext.Dic_commands.ContainsKey(commandId))
			{
				idtContext.Dic_commands[commandId].status = 1;
			}
		}

		[MessageNumber(0x13)]
		public void CheckHeart()
		{
			var idtContext = context.GetContext<IDTContext>();
			byte[] ReplyBuffer;
			if (context.CurrentPack.ReceiveBuffer[4] != 0xEF)
			{
				ReplyBuffer = IDTProtocolPack.ErrorReply(context.CurrentPack.CommandID,eReceivePackType.ErrorHeart);
			}
			else
			{
				ReplyBuffer = HeartReply(context.CurrentPack.CommandID,eReceivePackType.Success);
				idtContext.RefreshHeartTime();
			}
			context.Send(ReplyBuffer);
			if (idtContext.SendTableConnectionKey == Guid.Empty)
			{
					foreach (var item in clientManager.GetClients())
					{

						if (item.Context.GetContext<IDTContext>().Device.SN== idtContext.Device.SN)
						{
							int.TryParse(item.Context.GetContext<IDTContext>().Device.ProductType,out int productType);
							if (item.Context.GetContext<IDTContext>().Device.eProductType==eProductType.SendTable)
							{
								idtContext.SendTableConnectionKey = item.ConnectionID;
							}
						}
					}
			}
			if (idtContext.SendTableConnectionKey!=Guid.Empty)
			{
				if (clientManager.ContainsKey(idtContext.SendTableConnectionKey))
				{
					var sendTableClient= clientManager.GetClient(idtContext.SendTableConnectionKey);
					sendTableClient.Context.GetContext<IDTContext>().RefreshHeartTime();
				}
			}
			logger.Info("收到心跳包!");
		}

		[MessageNumber(0x15)]
		public void VersionUpgrade()
		{
			// msgforsignalr = "";
			byte[] versionBuf = new byte[1];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 2, versionBuf, 0, 1);

			byte[] manufactureBuf = new byte[2];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 4, manufactureBuf, 0, 2);
			string manufacture = Encoding.UTF8.GetString(manufactureBuf);

			byte[] productTypeBuf = new byte[4];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 6, productTypeBuf, 0, 4);
			string productType = BitConverter.ToString(productTypeBuf).Replace("-", "");
			var ptype = int.Parse(productType);


			byte[] idBuf = new byte[16];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 10, idBuf, 0, 16);
			string sn = Encoding.UTF8.GetString(idBuf);
			//socketConnectionHandler.AddDeviceSn(id, sn);

			byte[] wareVersionBuf = new byte[8];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 26, wareVersionBuf, 0, 8);
			string wareVersion = Encoding.UTF8.GetString(wareVersionBuf);

			byte[] singlePackMaxSizeBuf = new byte[2];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 34, singlePackMaxSizeBuf, 0, 2);
			string singlePackMaxSizeStr = BitConverter.ToString(singlePackMaxSizeBuf).Replace("-", "");
			int singlePackMaxSize = Convert.ToInt32($"0x{singlePackMaxSizeStr}", 16);
			//var singlePackMaxSize = int.Parse(Encoding.UTF8.GetString(singlePackMaxSizeBuf));

			//socketConnectionHandler.AddSocket(sn, handler, ptype);

			int clientType = 0;
			if (ptype == 64)
			{
				clientType = 0;
				logger.Info($"沙盘【{sn}】已连接，固件更新通道");
			}
			if (ptype == 65)
			{
				clientType = 2;
				logger.Info($"操作台【{sn}】已连接，固件更新通道");
			}

			cache.SetAsync($"clientType:{sn}", clientType, 0).Wait();
			var pv = cache.GetAsync<string>($"productversionid:{sn}").Result;
			if (string.IsNullOrEmpty(pv))
				return;
			var vh = versionUpgradeHanlder.SetFileCacheAsync(clientType, wareVersion, singlePackMaxSize, pv);
			vh.Wait();
			if (!vh.Result)
			{
				return;
			}

			 byte []replyBuffer = VersionUpgradeReply(context.CurrentPack.CommandID,eReceivePackType.Success, versionUpgradeHanlder._UpFileInfo.Size, versionUpgradeHanlder._UpFileInfo.PackNum, versionUpgradeHanlder._UpFileInfo.Version);

			context.Send(replyBuffer);
		}

		[MessageNumber(0x16)]
		public void VersionUpgradeData()
		{
			byte[] wareVersionBuf = new byte[8];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 4, wareVersionBuf, 0, 8);
			string wareVersion = Encoding.UTF8.GetString(wareVersionBuf);
			byte[] requestPackNumBuf = new byte[2];
			Array.Copy(context.CurrentPack.ReceiveBuffer, 12, requestPackNumBuf, 0, 2);
			string requestPackNumStr = BitConverter.ToString(requestPackNumBuf).Replace("-", "");
			int requestPackNum = Convert.ToInt32($"0x{requestPackNumStr}", 16);
			//int requestPackNum = int.Parse(Encoding.UTF8.GetString(requestPackNumBuf));
			IDTContext idtContext = context.GetContext<IDTContext>();
			logger.Info($"productversionid:{idtContext.Device.SN}");
			int clientType = cache.GetAsync<int>($"clientType:{idtContext.Device.SN}").Result;
			var pv = cache.GetAsync<string>($"productversionid:{idtContext.Device.SN}").Result;


			var totalPackNum = versionUpgradeHanlder.GetPackCount(wareVersion, pv, clientType);
			byte[] currentPackData = versionUpgradeHanlder.GetPackData(wareVersion, requestPackNum - 1, pv, clientType); //requestPackNum从1开始

			var currentPackDataLength = currentPackData == null ? 0 : currentPackData.Length;

			byte[] replyBuffer = VersionUpgradeDataReply(idtContext.CurrentPack.CommandID,eReceivePackType.Success, wareVersion, (int)totalPackNum, requestPackNum, currentPackDataLength, currentPackData);

			context.Send(replyBuffer);
		}

		private byte[] HeartReply(int commandId, eReceivePackType ReceivePackType)
		{
			return IDTProtocolPack.HeartReply(commandId,ReceivePackType);
		}
		private byte[] ReceiveDeviceInfoReply(int commandId, eReceivePackType ReceivePackType, string json)
		{
			return  IDTProtocolPack.ReceiveDeviceInfoReply(commandId,ReceivePackType,json);
		}
		private byte[] LoginReply(int commandId,eReceivePackType ReceivePackType,int updateflag= 0)
		{
			return IDTProtocolPack.LoginReply(commandId, ReceivePackType,configution.IpAddress,configution.Port,updateflag);
		}
		public byte[] VersionUpgradeReply(int commandId,eReceivePackType ReceivePackType, int totalSize, int totalPackNum, string firmwareVersion)
		{
			logger.Info($"更新程序包版本：{firmwareVersion}");
			return IDTProtocolPack.VersionUpgradeReply(commandId, ReceivePackType, totalSize, totalPackNum,firmwareVersion);
		}
		public byte[] VersionUpgradeDataReply(int commandId, eReceivePackType ReceivePackType, string firmwareVersion, int totalPackNum, int currentPackNum, int currentPackDataLength, byte[] currentPackData)
		{
			
			return IDTProtocolPack.VersionUpgradeDataReply( commandId,  ReceivePackType,  firmwareVersion,  totalPackNum,  currentPackNum,  currentPackDataLength,currentPackData);
		}

	}
}
